package com.xnyzc.lhy.resource.controller.oss;


import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.entity.HeadBash64;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.oss.OSSFileType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.order.entity.mq.OaCOrderPersonal;
import com.xnyzc.lhy.resource.entity.oss.OaOssFile;
import com.xnyzc.lhy.resource.feign.worksheet.IOaAuthService;
import com.xnyzc.lhy.resource.service.oss.IOaOssFileService;
import com.xnyzc.lhy.resource.util.BASE64DecodedMultipartFileUtil;
import com.xnyzc.lhy.resource.util.oss.IOSS;
import com.xnyzc.lhy.resource.util.oss.OSSFactory;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.bytecode.analysis.MultiType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * oss上传文件对照表 前端控制器
 * </p>
 *
 * @author haoyfa
 * @since 2019-10-19
 */
@Slf4j
@RestController
@RequestMapping("/oa/cos")
public class QCloudOssFileController {
    @Autowired
    IOaOssFileService iOaOssFileService;

    @Autowired
    OSSFactory ossFactory;

    @Autowired
    IOaAuthService oaAuthService;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 单文件上传
     *
     * @return
     */
    @ApiOperation(value = "单文件上传", notes = "单文件上传")
    @PostMapping(value = "uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Rv uploadFile(@ApiParam(name = "file", value = "文件") @RequestPart("file") MultipartFile file,
                         @ApiParam(name = "fileType", value = "文件类型") @RequestParam("fileType") String fileType) {
        if (CheckUtil.objIsEmpty(file) || CheckUtil.strIsEmpty(fileType)) {
            throw PangException.create(EErrorCode.missingArg);
        }
        // 上传文件流
        byte[] content;
        try {
            content = file.getBytes();
        } catch (IOException e) {
            log.info("文件内容为空，不可上传");
            throw PangException.create(EErrorCode.dataParseError);
        }

        // 获取文件名称
        String fileName = file.getOriginalFilename();

        String extendName = "";
        if (!CheckUtil.strIsEmpty(fileName)) {
            // 获取文件后缀
            extendName = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
        }

        // 文件名换成随机数
        fileName = String.valueOf(IDUtil.nextId());

        // oss服务存储路径
        String saveFilePath = OSSFileType.findByPath(fileType).getValue();
        // 保存文件相关信息
        Long fileId = iOaOssFileService.getFileId(fileName, extendName, saveFilePath);
        //上传文件存储路径
        String qCloudFileName = fileId + extendName;
        //获得文件存储路径
        String qCloudUrl = saveFilePath + qCloudFileName;

        log.info("============ 开始单上传文件 =============");
        // 初始化OSSClient实例
        IOSS ossClient = ossFactory.initializtionOSS();
        ossClient.uploadFile(qCloudUrl, content);

        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.getFileUrl(qCloudUrl);

        // 关闭OSSClient。
        ossClient.shutdown();

        log.info("============ 单文件上传结束 =============");

        // 返回数据
        Qd qd = Qd.create().add("fileId", fileId).add("fileUrl", url);

        return Rv.wrap(qd);
    }

    /**
     * 获取文件访问路径(单文件)
     *
     * @return
     */
    @ApiOperation(value = "获取文件访问路径", notes = "获取文件访问路径")
    @GetMapping(value = "getFileUrl")
    public Rv getFileUrl(@ApiParam(name = "fileId", value = "文件ID") Long fileId) {

        if (CheckUtil.objIsEmpty(fileId)) {
            throw PangException.create(EErrorCode.missingArg);
        }

        // 初始化OSSClient实例
        IOSS ossClient = ossFactory.initializtionOSS();

        OaOssFile oaOssFile = iOaOssFileService.getById(fileId);
        if (CheckUtil.objIsEmpty(oaOssFile)) {
            throw PangException.create(EErrorCode.unData);
        }

        StringBuilder fileUrl = new StringBuilder();
        fileUrl.append(oaOssFile.getFilePath()).append(oaOssFile.getOssFileId()).append(oaOssFile.getExtendName());
        URL url = ossClient.getFileUrl(String.valueOf(fileUrl));
        ossClient.shutdown();

        // 返回数据
        Qd qd = Qd.create().add("fileUrl", url);

        return Rv.wrap(qd);
    }

    /**
     * 获取录音文件路径
     *
     * @return
     */
    @ApiOperation(value = "获取录音文件路径", notes = "获取录音文件路径")
    @GetMapping(value = "getAudioFileUrl")
    public String getAudioFileUrl(@ApiParam(name = "orderNo", value = "录音名称") @RequestParam("orderNo") String orderNo) {

        if (CheckUtil.strIsEmpty(orderNo)) {
            log.error("录音文件名为空：{}", orderNo);
            return null;
        }

        // 初始化OSSClient实例
        IOSS ossClient = ossFactory.initializtionOSS();

        StringBuilder fileUrl = new StringBuilder();
        fileUrl.append("sound/").append(orderNo + ".mp3");
        boolean fileExist = ossClient.getFileMessage(String.valueOf(fileUrl));
        URL url = ossClient.getFileUrl(String.valueOf(fileUrl));
        ossClient.shutdown();
        String path = url.toString();
        if (CheckUtil.strIsEmpty(path)) {
            path = "";
        }
        if (!fileExist) {
            path = "";
        }
        OaCOrderPersonal oaCOrderPersonal = oaAuthService.billDetails(orderNo);
        if (CheckUtil.strIsNotEmpty(path) && CheckUtil.objIsNotEmpty(oaCOrderPersonal)) {
            Date date = new Date();
            Date createTime = oaCOrderPersonal.getCreateTime();
            Long cnt = (date.getTime() - createTime.getTime()) / 1000 / 60 / 60 / 24;
            if (cnt > 30) {
                path = "audio";
            }
        }
        return path;
    }

    /**
     * 多文件上传
     *
     * @return
     */
    @ApiOperation(value = "多文件上传", notes = "多文件上传")
    @PostMapping(value = "uploadFiles")
    public Rv uploadFiles(@ApiParam(name = "files", value = "文件") @RequestParam("files") MultipartFile[] files,
                          @ApiParam(name = "fileType", value = "文件类型") @RequestParam("fileType") String fileType) {
        if (CheckUtil.objIsEmpty(files) || CheckUtil.strIsEmpty(fileType)) {
            throw PangException.create(EErrorCode.missingArg);
        }
        // 文件数统计
        Integer count = 0;
        List<Qd> qdList = new ArrayList<>();
        // 初始化OSSClient实例
        IOSS ossClient = ossFactory.initializtionOSS();
        for (int i = 0; i < files.length; i++) {
            if (!files[i].isEmpty()) {
                // 上传文件流
                byte[] content;
                try {
                    content = files[i].getBytes();
                } catch (IOException e) {
                    log.info("文件内容为空，不可上传");
                    throw PangException.create(EErrorCode.dataParseError);
                }
                // 获取文件名称
                String fileName = files[i].getOriginalFilename();
                String extendName = "";
                if (!CheckUtil.strIsEmpty(fileName)) {
                    // 获取文件后缀
                    extendName = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
                }

                // 源文件名加随机数
                fileName = String.valueOf(IDUtil.nextId());

                // oss服务存储路径
                String saveFilePath = OSSFileType.findByPath(fileType).getValue();
                // 保存文件相关信息
                Long fileId = iOaOssFileService.getFileId(fileName, extendName, saveFilePath);
                //上传到阿里云时候的图片名称及图片存储路径
                String aliFileName = fileId + extendName;
                //获得头像在阿里云图片存储路径
                String aliUrl = saveFilePath + aliFileName;

                log.info("===========第{}个文件开始上传=========", i + 1);

                ossClient.uploadFile(aliUrl, content);
                URL url = ossClient.getFileUrl(aliUrl);
                count++;
                log.info("===========第{}个文件上传结束=========", i + 1);
                // 返回数据
                qdList.add(Qd.create().add("fileId", fileId).add("fileUrl", url));
            }
        }
        // 关闭OSSClient。
        ossClient.shutdown();

        return Rv.wrap(qdList);
    }

    /**
     * 用户头像上传
     * @param headBash64 文件
     * @return Rv
     */
    @PostMapping(value = "uploadHeadFile")
    public Rv uploadFile(@RequestBody HeadBash64 headBash64) {

        MultipartFile multipartFile = BASE64DecodedMultipartFileUtil.base64ToMultipart(headBash64.getHeadImg());
        return this.uploadFile(multipartFile, "1");

    }

    /**
     * 获取文件访问路径(多文件)
     *
     * @return
     */
    @ApiOperation(value = "获取多文件访问路径", notes = "获取多文件访问路径")
    @GetMapping(value = "getFileUrls")
    public Rv getFileUrls(@ApiParam(name = "fileIds", value = "多文件ID") String fileIds) {

        if (CheckUtil.objIsEmpty(fileIds)) {
            throw PangException.create(EErrorCode.missingArg);
        }

        // 初始化OSSClient实例
        IOSS ossClient = ossFactory.initializtionOSS();

        List<OaOssFile> oaOssFileList = iOaOssFileService.getFileUrl(fileIds);
        List<Qd> qdList = new ArrayList<>();
        for (OaOssFile oss : oaOssFileList) {
            StringBuilder fileUrl = new StringBuilder();
            fileUrl.append(oss.getFilePath()).append(oss.getOssFileId()).append(oss.getExtendName());

            URL url = ossClient.getFileUrl(String.valueOf(fileUrl));
            // 返回数据
            qdList.add(Qd.create().add("fileUrl", url));
        }

        ossClient.shutdown();
        return Rv.wrap(qdList);
    }

    /**
     * 微服务文件传输上传接口
     */
    @ApiOperation(value = "微服务单文件上传", notes = "微服务单文件上传")
    @PostMapping(value = "uploadPartFile")
    public Rv uploadPartFile(@ApiParam(name = "file", value = "文件") @RequestPart("file") MultipartFile file,
                             @ApiParam(name = "fileType", value = "文件类型") @RequestParam("fileType") String fileType) {
        log.info(fileType);
        return Rv.wrap(null);
    }

    /**
     * 获取腾讯COS临时秘钥
     */
    @ApiOperation(value = "获取腾讯COS临时秘钥", notes = "获取腾讯COS临时秘钥")
    @GetMapping(value = "getTemporary")
    public JSONObject getTemporary() {
        IOSS ossClient = ossFactory.initializtionOSS();
        if(CheckUtil.objIsEmpty(ossClient.getTemporary())){//验证临时秘钥是否为空
            throw PangException.create(EErrorCode.NO_SECRET_KEY);
        }
        String jsonStr = ossClient.getTemporary().toString();
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        return jsonObject;
    }

    /**
     * 获取 uploadId
     */
    @ApiOperation(value = "获取 uploadId", notes = "获取 uploadId")
    @PostMapping(value = "getUploadId")
    public String getUploadId(@RequestParam("savePath") String savePath) {
        IOSS ossClient = ossFactory.initializtionOSS();
        return ossClient.getUploadId(savePath);
    }
}
